import { Component, OnInit } from '@angular/core'
import { FormGroup, FormBuilder, Validators } from '@angular/forms'
import { ActivatedRoute } from '@angular/router'
import { Observable, of } from 'rxjs'
import { concatMap, switchMap, map } from 'rxjs/operators'
import { NzMessageService } from 'ng-zorro-antd'

import { NewPageAccessor } from '@shared/components/new-page/new-page.interface'
import { makeAllControlDirty, acquirerEditPermission, setupUserRoleTypeSelectionPermit } from 'app/utils/helpers'
import { DataService } from '@shared/services/data.service'
import { roleNameMinLength, roleNameMaxLength, roleDescMaxLength } from 'app/utils/contraints'
import { SettingsService } from '@delon/theme'
import { User } from '@shared/interfaces/user'
import { EUserType, ERoleType } from '@shared/enums'
import { IAamsItem } from '@shared/components/aams-select/aams-select.interface'
import { ERoleRoute } from '../../role.interface'
import { RoleService } from '../../role.service'
import { IRoleCreateFormData } from '@shared/interfaces/role'
import { I18NService } from '@core'

@Component({
  selector: 'app-role-new-basic-info',
  templateUrl: './role-new-basic-info.component.html',
  styles: [],
})
export class RoleNewBasicInfoComponent implements NewPageAccessor, OnInit {
  constructor(
    public settings: SettingsService,
    private msg: NzMessageService,
    private fb: FormBuilder,
    private dataService: DataService,
    private route: ActivatedRoute,
    private roleService: RoleService,
    private i18n: I18NService,
  ) {}
  data: any
  payload: IRoleCreateFormData
  form: FormGroup
  errorTips = {}

  userRoles = [
    { label: this.trans('ROLE_LEVEL.INSTITUTION'), value: ERoleType.Acquirer, key: EUserType.Institution },
    { label: this.trans('ROLE_LEVEL.AGENT'), value: ERoleType.Group, key: EUserType.Agent },
    { label: this.trans('ROLE_LEVEL.MERCHANT'), value: ERoleType.Merchant, key: EUserType.Merchant },
    { label: this.trans('ROLE_LEVEL.STORE'), value: ERoleType.Store, key: EUserType.Store },
  ]

  checkValid(): boolean {
    if (this.form.valid) {
      this.pushDataToStore()
      this.msg.success(this.trans('GENERAL.NOTIFICATION.VALIDATION_SUCCESS'))
      return true
    }

    makeAllControlDirty(this.form)
    return false
  }

  pushDataToStore(): void {
    const data: IRoleCreateFormData = this.form.getRawValue()
    if (this.payload && this.payload.functions) {
      data.functions = this.payload.functions
    }
    this.dataService.setRoleCreateData(data)
  }

  ngOnInit() {
    this.setupValidateForm()
    this.setupUserRoleSelectionPermit()
  }

  setupValidateForm() {
    const authUser = this.settings.user as User
    this.form = this.fb.group({
      roleName: [
        '',
        [Validators.required, Validators.minLength(roleNameMinLength), Validators.maxLength(roleNameMaxLength)],
      ],
      insCode: [
        {
          value: null,
          disabled: acquirerEditPermission(authUser),
        },
        [Validators.required],
      ],
      roleType: ['', [Validators.required]],
      roleDesc: ['', [Validators.required, Validators.maxLength(roleDescMaxLength)]],
    })

    this.roleFormData$().subscribe(data => {
      this.payload = data
      let institution: IAamsItem = {}
      // If data contain information should data info as first priority.
      if (data.insCode) {
        institution = data.insCode
      } else {
        // Else get the data from login user.
        institution = this.getUserInstitution(authUser)
      }
      institution.num = institution.code || null

      this.form.get('roleName').setValue(data.roleName)
      this.form.get('insCode').setValue(institution.code ? institution : null)
      this.form.get('roleType').setValue(data.roleType)
      this.form.get('roleDesc').setValue(data.roleDesc)
      this.initErrorTips()
    })
  }

  setupUserRoleSelectionPermit() {
    const authUser = this.settings.user as User
    this.userRoles = setupUserRoleTypeSelectionPermit(authUser, this.userRoles)
  }

  getUserInstitution(user: User): IAamsItem {
    switch (user.userType) {
      case EUserType.CIL:
      case EUserType.GenAdmin: {
        return {
          code: '',
          name: '',
          nameEN: '',
        }
      }
      default: {
        return {
          code: user.insCode,
          name: user.insName,
          nameEN: user.insNameEN,
        }
      }
    }
  }

  initErrorTips() {
    this.errorTips = {
      roleName: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('ROLE.ROLE_NAME') }),
        minlength: this.trans('VALIDATION.MIN_LENGTH', { length: roleNameMinLength }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: roleNameMaxLength }),
      },
      insCode: {
        required: this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('ROLE.OWNER_INSTITUTION') }),
      },
      roleType: {
        required: this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('ROLE.ROLE_LEVEL') }),
      },
      roleDesc: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('ROLE.ROLE_DESC') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: roleDescMaxLength }),
      },
    }
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }

  private roleFormData$(): Observable<IRoleCreateFormData> {
    return this.route.data.pipe(
      concatMap(routeData => {
        return this.dataService.roleCreateData$.value$.pipe(
          concatMap(value => {
            if (Object.keys(value).length) {
              return of(value)
            }

            if (routeData.routeName !== ERoleRoute.CopyRole) {
              return of({} as IRoleCreateFormData)
            }

            return this.route.params.pipe(
              switchMap(params => {
                const id = parseInt(params.id, 10)
                return this.roleService.getRoleById(id).pipe(
                  map(role => {
                    if (role.insCodes == null) role.insCodes = ['']
                    if (role.menus == null) role.menus = []

                    const formData: IRoleCreateFormData = {}
                    const ins: IAamsItem = {}
                    ins.code = role.insCodes[0]
                    ins.num = role.insCodes[0]
                    ins.name = role.insCodes[0]

                    formData.roleName = role.roleName
                    formData.insCode = ins
                    formData.roleType = role.roleType
                    formData.roleDesc = role.roleDesc
                    formData.functions = role.menus.map(m => m.menuId)
                    return formData
                  }),
                )
              }),
            )
          }),
        )
      }),
    )
  }
}
